/*
 * ClienteUsuario.cpp
 *
 *  Created on: 25/06/2011
 *      Author: chronos
 */

#include "ClienteUsuario.h"
//#include <iostream>
#include <unistd.h>
#include <string>
#include <stdlib.h>
#include "log/lockinglog.h"
#include <sstream>
using namespace std;

ClienteUsuario::ClienteUsuario(string nombre,bool debug) {
	this->pid = getpid();
	this->nombre= nombre;
	this->log = new lockinglog (debug,(char *) "log.txt");
	colaCliente = new Cola<Mi_Tipo_Mensaje> ("/bin/ls", pid);
	colaServidor = new Cola<Mi_Tipo_Mensaje> ("/bin/ls", 1);
	permito_salir=false;
	iniciarSesion();

}

ClienteUsuario::~ClienteUsuario() {
	// TODO Auto-generated destructor stub
	delete colaCliente;
}

void ClienteUsuario::enviarMensaje(int tipoDeMensaje,  int numero, string texto) {
	Mi_Tipo_Mensaje mensaje;
	mensaje.mtype = PETICION;
	mensaje.tipomensaje = tipoDeMensaje;
	mensaje.pidEmisor = pid;
	mensaje.pidReceptor = 0;
	mensaje.num = numero;

	strcpy(mensaje.mensaje, texto.c_str());
	stringstream ss;
	mensaje.recibido = false;
	stringstream log1;
	log1<< "Envio mensaje tipo:"<< tipoDeMensaje <<" Mensaje: "<< mensaje.mensaje <<endl;
	this->log->loguear((char*) log1.str().c_str());
	colaServidor->escribir(mensaje);
}

bool ClienteUsuario::recibirConfirmacion(int tipoMensaje) {
	Mi_Tipo_Mensaje mensaje;
	colaCliente->leer(RESPUESTA, &mensaje);

	return (mensaje.tipomensaje == tipoMensaje && mensaje.recibido == true);
	cout<<"recibe confirmacion de login"<<endl;
}

void ClienteUsuario::iniciarSesion() {

	// Si el cliente no recibe respuesta correcta del servidor, cierra su cola de mensajes y termina el programa (con error)

	this->log->loguear("Inicio Conexion con servidor\n");
	enviarMensaje(TIPO_MENSAJE_LOGIN, SALA_INICIAL,this->nombre);
	cerr << "Mensaje Enviado Esperando respuesta " << endl;
	this->log->loguear("Inicio Conexion con servidor\n");
	if (!recibirConfirmacion(TIPO_MENSAJE_LOGIN)) {
		cerr << "Error (2) de comunicacion al iniciar sesion con el servidor"<< endl;
		this->log->loguear("Error (2) de comunicacion al iniciar sesion con el servidor\n");

		delete this;
		exit(1);
	}
	this->log->loguear("Conexion con el servidor satisfactoria");
	cerr << "Conexion con el servidor satisfactoria" << endl;
}
bool ClienteUsuario::salir(){
	return permito_salir;
}

int ClienteUsuario::procesarMensajesDelServidor() {
	Mi_Tipo_Mensaje mensaje;
	mensaje.tipomensaje=0;
	//cout<<"espero por mensaje"<<endl;
	colaCliente->leer(0, &mensaje);
	//cerr<<"Cliente: Recibi mensaje del tipo: ["<<mensaje.tipomensaje<<"] con contenido:\n"<<mensaje.mensaje<<endl;

	switch (mensaje.tipomensaje) {
	case TIPO_MENSAJE_UNIRSE_A_SALA_ACEPTAR:
			this->log->loguear("Cliente Ingreso a sala\n");
			system("clear");
			cout << "Bienvenido a la Sala N°" << mensaje.num<< endl;
			cout << "Para salir, escriba \"/quit\"\n";
			cout << "Para listar los usuarios del canal, escriba \"/listar\"\n";
			return 1;
		break;
	case TIPO_MENSAJE_LISTAR_USUARIOS:
//		cerr<<"Cliente: Recibi mensaje del tipo: ["<<mensaje.tipomensaje<<"] con contenido:\n"<<mensaje.mensaje<<endl;

		cout<<"Usuarios en sala: "<<endl<<mensaje.mensaje<<endl;
		break;
	case TIPO_MENSAJE_LISTAR_SALAS:
		system("clear");
		cout<<"Salas Disponibles: "<<endl<<mensaje.mensaje<<endl;
		// TODO: recordar listar nombre y numero de las salas
		break;
	case TIPO_MENSAJE_ENVIAR_MENSAJE:
		this->log->loguear("Llega mensaje\n");
		cout<<mensaje.mensaje<<endl;
	//	cout<<"Mensaje Recibido OK"<<endl;
		return 1;
	break;


	case TIPO_MENSAJE_SALA_NO_ENCONTRADA:
		this->log->loguear("Sala no Encontrada\n");
		cout<<"Sala no Encontrada"<<endl;
		return -1;
	break;

	case TIPO_MENSAJE_SALA_NUEVA:

	cout << "Creada la Sala N°" << mensaje.num << " Nombre: " << mensaje.mensaje << endl;
	this->log->loguear("Creada la Sala \n");
	return 1;
	break;
	case TIPO_MENSAJE_SALA_YA_EXISTE:

		cout << "La Sala N°" << mensaje.num << " ya existe "<< endl;
		return -1;
		break;
	case TIPO_MENSAJE_LOGOFF:
		this->permito_salir=true;

		//cout<<"permito salir";
		break;
	default:
		return -1;
		break;
	}
return 1;
}

void ClienteUsuario::imprimirOpciones() {
	cout << "1: Crear nueva sala\n" << "2: Listar salas disponibles\n"
			<< "3: Unirse a Sala\n" << "4: Salir" << endl;
}

int ClienteUsuario::atenderUsuario(int entrada) {

//	int entrada = 0;
	int numero_de_sala=-1;
	string s_numero_de_sala;
	string nombre_de_sala;
//	cin >> entrada;


	switch (entrada) {
	case 1:
		do{

		cout << "Ingrese numero de la sala\n";
		cin >> s_numero_de_sala;
		numero_de_sala= atoi(s_numero_de_sala.c_str());
		if (numero_de_sala<=0){
			system("clear");
			cout<<"Numero no valido"<<endl;
		}
		}while(numero_de_sala<=0);

		cout << "Ingrese el nombre de la sala\n";
		cin >> nombre_de_sala;

		// Elimina las lineas recien impresas en pantalla
		system("clear");
		enviarMensaje(TIPO_MENSAJE_SALA_NUEVA, numero_de_sala, nombre_de_sala);
		if (this->procesarMensajesDelServidor()==1) return -1;

		break;

	case 2:
		enviarMensaje(TIPO_MENSAJE_LISTAR_SALAS,0,"");

		if (this->procesarMensajesDelServidor()==1) return -1;

		break;

	case 3:
		cout << "Ingrese Numero de Sala al cual quiere ingresar" << endl;
		cin >> numero_de_sala;

		// Elimina las lineas recien impresas en pantalla

		cout<<"envio mensaje tipo:"<<TIPO_MENSAJE_UNIRSE_A_SALA<<" numero sala:"<<numero_de_sala<<endl;
		enviarMensaje(TIPO_MENSAJE_UNIRSE_A_SALA, numero_de_sala,"");

		if (this->procesarMensajesDelServidor()==1) return 3;
		break;

	case 4:
		//cout<<"Mando mensaje de salida"<<endl;
		enviarMensaje(TIPO_MENSAJE_LOGOFF,0,"");
		if (this->procesarMensajesDelServidor()==1) return 0;
		else return 0;
		break;

	default:
		cout<<"Opcion no valida\n Por favor vuelva a intentar\n";
		return -1;
		break;
	}

	return -1;

}

	void ClienteUsuario::chatear(string nombre) {
		string mensaje;

		do {
//			cin>>mensaje;
			getline(cin, mensaje);
			if (mensaje.compare("/listar") == 0) {
				enviarMensaje(TIPO_MENSAJE_LISTAR_USUARIOS,0,"");
			}
			else {
				if (mensaje.compare("/quit") == 0) {

					enviarMensaje(TIPO_MENSAJE_LOGOFF, 0, "");

				}
				else
				{
					if (mensaje.compare("/historial") == 0) {
						cout<<endl;
						enviarMensaje(TIPO_MENSAJE_HISTORIA, 0, "");
					}
					else
					{
						enviarMensaje(TIPO_MENSAJE_ENVIAR_MENSAJE, 0, nombre + ">>" + mensaje);
					}
				}

			}
		} while (mensaje.compare("/quit")!=0);
	}
